package org.example.client;

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

import javax.net.ssl.*;
import java.io.File;
import java.io.InputStream;
import java.nio.file.Files;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;

public class OneWayClient {
    //安全传输层协议
    private static final String PROTOCOL = "TLS";
    // JKS/PKCS12
    private static final String KEY_KEYSTORE_TYPE = "PKCS12";

    private static SSLSocketFactory getSocketFactory(TrustManager[] trustManagers) throws Exception {
        SSLSocketFactory socketFactory = null;
        SSLContext sslContext = SSLContext.getInstance(PROTOCOL);
        sslContext.init(null, trustManagers, new SecureRandom());
        socketFactory = sslContext.getSocketFactory();
        return socketFactory;
    }

    private static TrustManager[] getTrustManagers(String cerPath) throws Exception {
        InputStream cerInputStream = Files.newInputStream(new File(cerPath).toPath());
        TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        KeyStore keyStore = KeyStore.getInstance(KEY_KEYSTORE_TYPE);
        //加载证书
        CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
        Certificate ca = certificateFactory.generateCertificate(cerInputStream);
        keyStore.load(null, null);
        //设置公钥
        keyStore.setCertificateEntry("server", ca);
        trustManagerFactory.init(keyStore);
        TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
        return trustManagers;
    }

    public static void main(String[] args) throws Exception {
        //获取SSLSocketFactory
        String certPath = "C:\\Users\\zw531\\Workspace\\spring-boot-sample\\spring-boot-ssl\\src\\main\\resources\\cert\\oneway\\server.cer";//服务端公钥
        //发送请求
        String url = "https://127.0.0.1:8080/trustAll";
        OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();
        TrustManager[] trustManagers = getTrustManagers(certPath);
        SSLSocketFactory socketFactory = getSocketFactory(trustManagers);
        clientBuilder.sslSocketFactory(socketFactory, (X509TrustManager) trustManagers[0]);
        //解决报错javax.net.ssl.SSLPeerUnverifiedException: Hostname 127.0.0.1 not verified
        clientBuilder.hostnameVerifier(new HostnameVerifier() {
            @Override
            public boolean verify(String s, SSLSession sslSession) {
                System.out.println("主机:" + s);
                return true;
            }
        });
        OkHttpClient client = clientBuilder.build();

        Request.Builder builder = new Request.Builder().url(url);
        Request request = builder.build();

        Response response = client.newCall(request).execute();
        String result = response.body().string();
        //打印请求结果
        System.out.println(result);
    }
}
